﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using User.Api.Models;

namespace User.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : BaseController
    {
        private readonly UserDbContext _userContext;
        private readonly ILogger<UserController> _logger;
        public UserController(UserDbContext userContext, ILogger<UserController> logger)
        {
            _userContext = userContext;
            _logger = logger;

        }
        /// <summary>
        /// 检查或者创建用户  但其那手机号码不存在的时候创建
        /// </summary>
        /// <returns></returns>
        [HttpPost("check-or-create")]
        public async Task<ActionResult> CheckOrCreate([FromForm]string phone)
        {

            var user = await _userContext.Users.SingleOrDefaultAsync(s => s.Phone == phone);
            if (user == null)
            {
                user = new Users() { Phone = phone };
                await _userContext.Users.AddAsync(user);
                await _userContext.SaveChangesAsync();
            }
            //throw new ApplicationException("");
            return Ok(user.Id);

        }

        [HttpGet]
        public async Task<IActionResult> Get()
        {
            var user = await _userContext.Users.AsNoTracking().
            Include(u => u.Properties).
            SingleOrDefaultAsync(s => s.Id == UserIdentity.UserId);

            if (user == null)
                throw new UserOperationException($"错误的用户上下文id:{UserIdentity.UserId}");
            return Json(user);
        }

        [HttpPatch]
        public async Task<IActionResult> Patch(JsonPatchDocument<Users> patch)
        {
            var user = await _userContext.Users.SingleOrDefaultAsync(u => u.Id == UserIdentity.UserId);
            if (user == null)
                throw new UserOperationException($"错误的用户上下文id:{UserIdentity.UserId}");

            patch.ApplyTo(user);

            var originProperties = await _userContext.UserProperty.AsNoTracking().Where(s => s.UserId == user.Id).ToListAsync();
            var allProperties = originProperties.Distinct();
            if (user.Properties != null)
            {
                allProperties = originProperties.Union(user.Properties).Distinct();
            }

            var removeProperties = allProperties;
            var newProperties = allProperties.Except(originProperties);
            if (removeProperties != null)
            {
                _userContext.UserProperty.RemoveRange(removeProperties);
            }
            if (newProperties != null)
            {
                foreach (var item in newProperties)
                {
                    item.UserId = user.Id;
                }
                await _userContext.AddRangeAsync(newProperties);
            }
            _userContext.Users.Update(user);
            await _userContext.SaveChangesAsync();
            return Json(user);
        }
        [HttpGet("tags")]
        public async Task<IActionResult> GetUerTags()
        {

            var result = await _userContext.UserTag.Where(u => u.UserId == UserIdentity.UserId).ToListAsync();
            return Ok(result);
        }

        [HttpPost("search")]
        public async Task<IActionResult> Search(string phone)
        {
            var result = await _userContext.Users.Include(u => u.Properties)
              .SingleOrDefaultAsync(u => u.Id == UserIdentity.UserId && u.Phone == phone);
            return Ok(result);
        }
        [HttpPost("tags")]
        public async Task<IActionResult> UpdateUserTags([FromBody]List<string> tags)
        {
            var originTags = await _userContext.UserTag.Where(u => u.UserId == UserIdentity.UserId).ToListAsync();
            var newTags = tags.Except(originTags.Select(t => t.Tag));
            await _userContext.UserTag.AddRangeAsync(newTags.Select(t => new UserTag
            {
                CreateTime = DateTime.Now,
                UserId = UserIdentity.UserId,
                Tag = t
            }));
            await _userContext.SaveChangesAsync();
            return Ok();
        }
    }
}
